package com.finna.tenant.service.impl;

import com.finna.tenant.dto.*;
import com.finna.tenant.dto.RoleDTO.RoleCreateRequest;
import com.finna.tenant.dto.RoleDTO.RoleListRequest;
import com.finna.tenant.dto.RoleDTO.RoleResponse;
import com.finna.tenant.dto.RoleDTO.RoleUpdateRequest;
import com.finna.tenant.entity.Role;
import com.finna.tenant.mapper.RoleMapper;
import com.finna.tenant.service.RoleService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 角色Service实现
 */
@Service
public class RoleServiceImpl implements RoleService {
    
    private static final Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class);
    
    private static final String ADMIN_ROLE_NAME = "超级管理员";
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Override
    @Transactional
    public RoleResponse create(RoleCreateRequest request) {
        // 检查角色名称是否已存在
        Role existingRole = roleMapper.selectByName(request.getName());
        if (existingRole != null) {
            throw new RuntimeException("角色名称已存在");
        }
        
        // 创建角色
        Role role = new Role();
        role.setName(request.getName());
        role.setDescription(request.getDescription());
        role.setStatus(request.getStatus() != null ? request.getStatus() : true);
        role.setMetaInfo(request.getMetaInfo());
        role.setCreateTime(LocalDateTime.now());
        role.setUpdateTime(LocalDateTime.now());
        role.setDeleted(false);
        
        roleMapper.insert(role);
        logger.info("创建角色成功: id={}, name={}", role.getId(), role.getName());
        
        return convertToResponse(role);
    }
    
    @Override
    @Transactional
    public RoleResponse update(Long id, RoleUpdateRequest request) {
        Role role = roleMapper.selectById(id);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }
        
        // 检查是否为超级管理员角色，不允许修改
        if (ADMIN_ROLE_NAME.equals(role.getName())) {
            throw new RuntimeException("超级管理员角色不允许修改");
        }
        
        if (request.getName() != null) {
            // 检查新名称是否与其他角色重复
            Role existingRole = roleMapper.selectByName(request.getName());
            if (existingRole != null && !existingRole.getId().equals(id)) {
                throw new RuntimeException("角色名称已存在");
            }
            role.setName(request.getName());
        }
        if (request.getDescription() != null) {
            role.setDescription(request.getDescription());
        }
        if (request.getStatus() != null) {
            role.setStatus(request.getStatus());
        }
        if (request.getMetaInfo() != null) {
            role.setMetaInfo(request.getMetaInfo());
        }
        role.setUpdateTime(LocalDateTime.now());
        
        roleMapper.updateById(role);
        logger.info("修改角色成功: id={}", id);
        
        return convertToResponse(role);
    }
    
    @Override
    @Transactional
    public void delete(Long id) {
        Role role = roleMapper.selectById(id);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }
        
        // 检查是否为超级管理员角色，不允许删除
        if (ADMIN_ROLE_NAME.equals(role.getName())) {
            throw new RuntimeException("超级管理员角色不允许删除");
        }
        
        // 软删除角色
        roleMapper.deleteById(id);
        
        logger.info("删除角色成功: id={}", id);
    }
    
    @Override
    public RoleResponse getById(Long id) {
        Role role = roleMapper.selectById(id);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }
        return convertToResponse(role);
    }
    
    @Override
    public List<RoleResponse> getAll() {
        List<Role> roles = roleMapper.selectAll();
        return roles.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }
    
    @Override
    public PageResponse<RoleResponse> list(RoleListRequest request) {
        // 构建查询参数
        Map<String, Object> params = new HashMap<>();
        if (request.getName() != null && !request.getName().isEmpty()) {
            params.put("name", request.getName());
        }
        if (request.getStatus() != null) {
            params.put("status", request.getStatus());
        }
        
        // 获取超级管理员角色ID（用于排除）
        Role adminRole = roleMapper.selectByName(ADMIN_ROLE_NAME);
        Long adminRoleId = adminRole != null ? adminRole.getId() : null;
        
        // 分页参数
        Integer page = request.getPage() != null ? request.getPage() : 1;
        Integer pageSize = request.getPageSize() != null ? request.getPageSize() : 10;
        if (pageSize > 100) {
            pageSize = 100;
        }
        
        // 使用PageHelper进行分页，查询角色列表（排除超级管理员）
        PageHelper.startPage(page, pageSize);
        List<Role> roles;
        if (adminRoleId != null) {
            roles = roleMapper.selectListExclude(params, adminRoleId);
        } else {
            roles = roleMapper.selectList(params);
        }
        PageInfo<Role> pageInfo = new PageInfo<>(roles);
        
        // 转换为响应对象
        List<RoleResponse> responses = pageInfo.getList().stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        
        return new PageResponse<>(responses, pageInfo.getTotal(), page, pageSize);
    }
    
    /**
     * 转换为响应对象
     */
    private RoleResponse convertToResponse(Role role) {
        RoleResponse response = new RoleResponse();
        response.setId(role.getId());
        response.setName(role.getName());
        response.setDescription(role.getDescription());
        response.setStatus(role.getStatus());
        response.setMetaInfo(role.getMetaInfo());
        response.setCreatedAt(role.getCreateTime());
        response.setUpdatedAt(role.getUpdateTime());
        return response;
    }
}

